/*
 * Copyright (c) 2005, 2014 vacoor
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.vacoor.nothing.security.logging;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.impl.StaticLoggerBinder;
import org.vacoor.nothing.security.logging.jul.JulWatcher;
import org.vacoor.nothing.security.logging.log4j.Log4jWatcher;

import java.util.Collection;
import java.util.List;

//import org.apache.solr.common.SolrDocument;
//import org.apache.solr.common.SolrDocumentList;
//import org.apache.solr.core.SolrResourceLoader;
//import org.apache.solr.logging.jul.JulWatcher;
//import org.apache.solr.logging.log4j.Log4jWatcher;

public abstract class LogWatcher<E> {
    private static final Logger LOG = LoggerFactory.getLogger(LogWatcher.class);

    protected CircularList<E> history;
    protected long last = -1L;

    public abstract String getName();

    public abstract List<String> getAllLevels();

    public abstract void setLogLevel(String paramString1, String paramString2);

    public abstract Collection<LoggerInfo> getAllLoggers();

    public abstract void setThreshold(String paramString);

    public abstract String getThreshold();

    public void add(E event, long timestamp) {
        System.out.println("日志事件" + event);

        this.history.add(event);
        this.last = timestamp;
    }

    public long getLastEvent() {
        return this.last;
    }

    public int getHistorySize() {
        return this.history == null ? -1 : this.history.getBufferSize();
    }

    /*
    public SolrDocumentList getHistory(long since, AtomicBoolean found) {
        if (this.history == null) {
            return null;
        }

        SolrDocumentList docs = new SolrDocumentList();
        Iterator iter = this.history.iterator();
        while (iter.hasNext()) {
            Object e = iter.next();
            long ts = getTimestamp(e);
            if ((ts == since) &&
                    (found != null)) {
                found.set(true);
            }

            if (ts > since) {
                docs.add(toSolrDocument(e));
            }
        }
        docs.setNumFound(docs.size());
        return docs;
    }
    */

    public abstract long getTimestamp(E event);

    /*
    public abstract SolrDocument toSolrDocument(E paramE);
    */

    public abstract void registerListener(ListenerConfig paramListenerConfig);

    public void reset() {
        this.history.clear();
        this.last = -1L;
    }

    public static LogWatcher newRegisteredLogWatcher(LogWatcherConfig config/*, SolrResourceLoader loader*/) {
        if (!config.isEnabled()) {
            LOG.info("A LogWatcher is not enabled");
            return null;
        }

        LogWatcher watcher = createWatcher(config/*, loader*/);

        if ((watcher != null) && (config.getWatcherSize() > 0)) {
            LOG.info("Registering Log Listener [{}]", watcher.getName());

            watcher.registerListener(config.asListenerConfig());
        }

        return watcher;
    }

    private static LogWatcher createWatcher(LogWatcherConfig config/*, SolrResourceLoader loader*/) {
        String loggingClass = config.getLoggingClass();
        String slf4jImpl;
        try {
            slf4jImpl = StaticLoggerBinder.getSingleton().getLoggerFactoryClassStr();
            LOG.info("SLF4J impl is " + slf4jImpl);
            if (loggingClass == null) {
                if ("org.slf4j.impl.Log4jLoggerFactory".equals(slf4jImpl))
                    loggingClass = "Log4j";
                else if (slf4jImpl.indexOf("JDK") > 0) {
                    loggingClass = "JUL";
                }
            }
        } catch (Throwable e) {
            LOG.warn("Unable to read SLF4J version.  LogWatcher will be disabled: " + e);

            if ((e instanceof OutOfMemoryError)) {
                throw ((OutOfMemoryError) e);
            }
            return null;
        }

        if (loggingClass == null) {
            LOG.info("No LogWatcher configured");
            return null;
        }

        if ("JUL".equalsIgnoreCase(loggingClass)) {
            return new JulWatcher(slf4jImpl);
        }
        if ("Log4j".equals(loggingClass)) {
            return new Log4jWatcher(slf4jImpl);
        }
        /*
        try {
            return loader != null ? (LogWatcher) loader.newInstance(fname, LogWatcher.class) : null;
        } catch (Throwable e) {
            LOG.warn("Unable to load LogWatcher {}: {}", fname, e);
            if ((e instanceof OutOfMemoryError)) {
                throw ((OutOfMemoryError) e);
            }
        }
        */

        return null;
    }

    public static void main(String[] args) {
        LogWatcher<?> watcher = LogWatcher.newRegisteredLogWatcher(new LogWatcherConfig(true, null, "TRACE", 100));
        System.out.println(watcher.getName());
        LOG.debug("heh");
    }
}